using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace Hoshimi
{
    public abstract class Unit : Component
	{
		#region Variables
		
		public Component myFather			= null;
		public StateMachine myStateMachine	= null;

		#endregion
		
		#region Getters & Setters

		public virtual bool IsGroup { get { return false; } }
		public virtual bool IsBot	{ get { return false; } }

		#endregion

		#region Methods

		/// <summary>
		/// Initialize the state machine
		/// </summary>
		/// <param name="aFactory">Factory used to build the state machine</param>
		public void InitStateMachine( AbstractSMFactory aFactory ) 
		{
			myStateMachine = aFactory.CreateStateMachine( this );
		}

		/// <summary>
		/// Check the life of the unit
		/// </summary>
		/// <returns>Return true if alive, otherwise false and tidy</returns>
        public abstract bool IsAlive();

		/// <summary>
		/// Play the unit's decision turn
		/// </summary>
		/// <returns>Returns true if the state has blocked the unit for this (and only this) turn</returns>
		public virtual bool Play() 
		{
			if ( myStateMachine == null ) return true; // No state machine, no action

			try
			{
				return myStateMachine.Play();
			}
			#if DEBUG
			catch (Exception e)
			{
				myPlayer.PrintException(e);

				// Pour savoir quand ca crash...
				Debug.Assert(false, e.Message, e.StackTrace);
				return true;
			}
			#else
			catch (Exception e)
			{
				myPlayer.PrintException(e);

				return true;
			}
			#endif
			
		}

		#endregion

		#region Ctor
		
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="player">Environment</param>
		/// <param name="aFactory">Factory used to build the state machine. If it is null, do not forget to set it later</param>
		public Unit(Component father, AbstractSMFactory aFactory ) 
            : base()
		{
			this.myFather = father;

			if ( aFactory != null )
				InitStateMachine( aFactory );
		}

        public Unit()
            : base()
        {
        }

		#endregion
		
	}
}
